package com.elcom.roaming.common.util.match;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;

public abstract class Matching implements Runnable{

	private String name;
	private BlockingQueue<ObjectInput> queue;
	private ConcurrentHashMap<ObjectKey, ObjectValue> map;
	private boolean stop;
	protected Logger logger;
	
	public Matching() {
		this.stop = false;
	}

	public String getName(){
		return name;
	}
	
	public void setQueue(BlockingQueue<ObjectInput> queue) {
		this.queue = queue;
	}

	public void setMap(ConcurrentHashMap<ObjectKey, ObjectValue> map) {
		this.map = map;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Logger getLogger() {
		return logger;
	}

	public void setLogger(Logger logger) {
		this.logger = logger;
	}

	public abstract void forward(ObjectInput obj);
	
	@Override
	public void run() {
		logger.info("Started...");
		while (!stop) {
			ObjectInput obj = null;
			try {
				obj = queue.take();
			} catch (InterruptedException e1) {
				logger.error("Take element from queue error." + e1);
			}
			if (obj != null) {
				int code = MatchingObjects.NOT_FOUND_PUT;
				try {
					code = MatchingObjects.matchObject(obj, map);
				} catch (Exception e) {
					logger.error("Matching error: " + obj.toString(), e);
				} 
				if ( code == MatchingObjects.FOUND_FORWARD ) {
					forward(obj);
				} else if ( code == MatchingObjects.NOT_FOUND_PUT ) {
//					logger.info("Put into HashMap: " + obj.toString());
				} else if ( code == MatchingObjects.MAP_FULL ) {
					logger.error("REJECTED - Matching Map is full: " + obj.toString());
				}
			} else {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
